/* Run a function for each element in array */
function each(func, array) {
    for(var i=0; i < array.length; i++) {
        func(array[i]);
    }    
}

/* Return only elements in array that match func */
function filter(func, array) {
    var output = Array();
    for(var i=0; i < array.length; i++) {
        if (func(array[i])) {
            output.push(array[i]);
        }
    }    
    return output;
}

/* Remove a div entry from a list */
function remove(link) {
    var div = link.parentNode;
    var main_div = div.parentNode;
    main_div.removeChild(div);    
}

/* Add a new entry to a list interpolating html contents */
function add(link, name, value, html_list_entry) {
    var main_div = link.previousSibling;
    html = html_list_entry.replace('${name}', name).replace('${value}', value)
    new_div = document.createElement("div");
    new_div.innerHTML = html;
    main_div.appendChild(new_div);
    divs = main_div.getElementsByTagName("div");
    if (divs.length > 1) {
        last_inputs = divs[divs.length-2].getElementsByTagName("input");
        new_inputs = new_div.getElementsByTagName("input");
        for(var i=0; i < last_inputs.length; i++) {
            new_inputs[i].value = last_inputs[i].value;
        }
    }
}

/* Run a callback for each child element in element with tag 'tagname' */
function process_tags(element, tagname, callback) {
    var elements = element.getElementsByTagName(tagname);
    for (var j=0; j < elements.length; j++) {
        callback(elements[j]);
    }
}

/* Disable input/select/a in a array of elements ID */
function set_visibility_for_elements(array, state) {
    for(var i=0; i < array.length; i++) {
        element = document.getElementById(array[i]);
        if (!element) {
            alert("Id not found: " + array[i]);
            continue;
        }
        process_tags(element, 'input', function(x) { x.disabled = !state; });
        process_tags(element, 'select', function(x) { x.disabled = !state; });
        process_tags(element, 'a', function(x) { 
            x.style.display = (state ? '': 'none'); });
    }
}

/* Show/hide groups and params when a select or radio input change its value */
function set_visibility(element) {
    var name = element.name;
    if (!showinfo[name] || !showinfo[name][element.value])
        return false;
    array = showinfo[name][element.value]    
    enable = array[0];
    disable = array[1];
    check = array[2];
    set_visibility_for_elements(enable, true);
    set_visibility_for_elements(disable, false);
    each(function(id) { set_all_visibility(document.getElementById(id)); }, check);
}
    
/* Run visibility function for all select/input elements */ 
function set_all_visibility(element) {
    each(function(select) {
            if (!select.disabled)
                set_visibility(select);
        },
        element.getElementsByTagName("select"));
    each(function(input) {            
            if (input.type == 'radio' && input.checked && !input.disabled)
                set_visibility(input);
        }, 
        element.getElementsByTagName("input"));
}

/* On window load set visibility for the whole document */
window.onload = function() {
    set_all_visibility(document);
}
